﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using System.Drawing;

namespace Melos
{
    /**
     * Picture resizer worker
     * Takes work from a queue, resizes the pictures to a different blob partition, and puts 
     * a pointer to the resulting object into another queue.
     */
    public class WorkerRole : RoleEntryPoint
    {
        private CloudStorageAccount sa;
        WorkQueue wq;
        ResultQueue rq;
        BlobHandler bh;
        /**
         * Worker entry point, called after initialization
         */ 
        public override void Run()
        {
            // This is a sample worker implementation. Replace with your logic.
            Trace.WriteLine("WorkerRole1 entry point called", "Information");

            //string rootPath = RoleEnvironment.GetLocalResource("Teszt").RootPath;
            //FileInfo fi = new FileInfo(rootPath + "ize.txt");
            //fi.Create();

            // this below is initialization, most probably should go to OnStart()
            sa = CloudStorageAccount.DevelopmentStorageAccount;
            wq = new WorkQueue(sa);
            rq = new ResultQueue(sa);
            bh = new BlobHandler(sa);
            /*msg = new CloudQueueMessage("aaaa");
            CloudQueue cq = cqc.GetQueueReference("testQueue");
            cq.AddMessage(msg);*/


            while (true)
            {
                processQueueMessage(wq.getItem());
                Trace.WriteLine("Working", "Information");
            }
        }
        /**
         * get a queue message, resize it, write the result to a blob, and write the blob address to the result queue
         */
        private void processQueueMessage(WorkQueueItem i)
        {
            Trace.WriteLine(i.ToString());

            rq.putItem(new ResultQueueItem()
            {
                blobAddress = bh.putStream(
                    resizeImage(bh.getStream(i.blobAddress), i.maxSize), "thumbnails")
            });
            wq.itemDone();
        }

        /**
         * resize an image to height of maxSize (misleading variable name... :) )
         */
        private Stream resizeImage(Stream s, int maxSize)
        {
            Image image = System.Drawing.Image.FromStream(s);
            float aspect = ((float)image.Width) / ((float)image.Height);
            int newWidth = Convert.ToInt32(((float)maxSize) * aspect);
            int newHeight = maxSize;
            Trace.WriteLine("resizeImage: " + image.Height + " ," + image.Width + " ," + aspect + ", " + newWidth + ", " + newHeight);

            Bitmap stage1 = new Bitmap(s);
            Bitmap stage2 = new Bitmap(stage1, newWidth, newHeight);

            //Image thumbnail = new Bitmap(newWidth, newHeight);
            //Graphics graphic = Graphics.FromImage(thumbnail);
            //graphic.DrawImage(image, 0, 0, newWidth, newHeight);

            Stream outputStream = new MemoryStream();
            stage2.Save(outputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            outputStream.Seek(0, SeekOrigin.Begin);

            return outputStream;
        }
        // default OnStart stub
        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            DiagnosticMonitor.Start("DiagnosticsConnectionString");

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            RoleEnvironment.Changing += RoleEnvironmentChanging;

            return base.OnStart();
        }

        // default RoleEnvironmentChanging stub
        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
        {
            // If a configuration setting is changing
            if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                e.Cancel = true;
            }
        }
    }
}
